package DataProcess;

import Stage.Stage1;
import baseAPI.AlertStage;
import baseAPI.Database;
import baseAPI.MyServer;
import baseClass.*;
import com.github.wxpay.sdk.Order;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Modality;
import javafx.stage.Stage;

import javax.xml.soap.Text;
import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;


public class CheckInAndOutPage {
    private static MyServer server;
    private static Database database;
    private static Pane pane;
    private static CheckBox singleCheckBox, doubleCheckBox, familyCheckBox, presidentCheckBox, luxuryCheckBox, coupleCheckBox;
    private static TableColumn<RoomTable, String> tcRoomNum, tcRoomType, tcRoomStatus, tcRoomPrice;
    private static TableView<RoomTable> tableView = new TableView<>();
    private static TextField nameText, ageText, idNumText, numText, roomNumText, checkOutText;
    private static Button btnInquire, btnCheckIn, btnCheckOut, btnClear;
    private static RadioButton radioMan, radioWoman;

    public static void bind(Parent checkInAndOut, Database database, MyServer server){
        CheckInAndOutPage.server = server;//服务器初始化
        CheckInAndOutPage.database = database;//数据库初始化

        //控件绑定
        btnInquire = (Button)checkInAndOut.lookup("#btnInquire");
        singleCheckBox = (CheckBox)checkInAndOut.lookup("#singleCheckBox");
        doubleCheckBox = (CheckBox)checkInAndOut.lookup("#doubleCheckBox");
        familyCheckBox = (CheckBox)checkInAndOut.lookup("#familyCheckBox");
        presidentCheckBox = (CheckBox)checkInAndOut.lookup("#presidentCheckBox");
        luxuryCheckBox = (CheckBox)checkInAndOut.lookup("#luxuryCheckBox");
        coupleCheckBox = (CheckBox)checkInAndOut.lookup("#coupleCheckBox");
        nameText = (TextField)checkInAndOut.lookup("#nameText");
        ageText = (TextField)checkInAndOut.lookup("#ageText");
        idNumText = (TextField)checkInAndOut.lookup("#idNumText");
        numText = (TextField)checkInAndOut.lookup("#numText");
        roomNumText = (TextField)checkInAndOut.lookup("#roomNumText");
        roomNumText.setEditable(false);//不允许手动输入
        checkOutText = (TextField)checkInAndOut.lookup("#checkOutText");
        btnCheckIn = (Button)checkInAndOut.lookup("#btnCheckIn");
        btnCheckOut = (Button)checkInAndOut.lookup("#btnCheckOut");
        btnClear = (Button)checkInAndOut.lookup("#btnClear");
        pane = (Pane)checkInAndOut.lookup("#pane");
        radioMan = (RadioButton)checkInAndOut.lookup("#radioMan");
        radioWoman = (RadioButton)checkInAndOut.lookup("#radioWoman");

        //radioButton设为一组
        ToggleGroup toggleGroup = new ToggleGroup();
        radioMan.setToggleGroup(toggleGroup);
        radioWoman.setToggleGroup(toggleGroup);
        radioWoman.setSelected(true);

        //新建表格
        pane.getChildren().add(tableView);
        tableView.setLayoutX(421);
        tableView.setLayoutY(40);
        tableView.setPrefWidth(695);
        tableView.setPrefHeight(748);
        tableView.setEditable(false);//表格不可编辑

        //新建列
        tcRoomNum = new TableColumn<>("房号");
        tcRoomType = new TableColumn<>("房间类型");
        tcRoomStatus = new TableColumn<>("房间状态");
        tcRoomPrice = new TableColumn<>("价格");

        tcRoomNum.setCellValueFactory(new PropertyValueFactory<RoomTable, String>("roomNumber"));
        tcRoomType.setCellValueFactory(new PropertyValueFactory<RoomTable, String>("roomKind"));
        tcRoomStatus.setCellValueFactory(new PropertyValueFactory<RoomTable, String>("status"));
        tcRoomPrice.setCellValueFactory(new PropertyValueFactory<RoomTable, String>("price"));

        tableView.getColumns().addAll(tcRoomNum, tcRoomType, tcRoomStatus, tcRoomPrice);
        tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        btnInquire.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                inquireRooms();
            }
        });

        singleCheckBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                inquireRooms();
            }
        });

        doubleCheckBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                inquireRooms();
            }
        });

        familyCheckBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                inquireRooms();
            }
        });

        coupleCheckBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                inquireRooms();
            }
        });

        luxuryCheckBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                inquireRooms();
            }
        });

        presidentCheckBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                inquireRooms();
            }
        });

        btnCheckIn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                checkIn();
            }
        });

        tableView.getSelectionModel().selectedItemProperty().addListener(//选中某一行后显示房间号
                new ChangeListener<RoomTable>() {
                    @Override
                    public void changed(
                            ObservableValue<? extends RoomTable> observableValue,
                            RoomTable oldItem, RoomTable newItem) {
                            if(newItem != null){
                                roomNumText.setText(newItem.getRoomNumber());
                            }
                    }
                });

        btnCheckOut.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                checkOut();
                checkOutText.clear();
            }
        });

        btnClear.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent event){
                nameText.clear();
                ageText.clear();
                idNumText.clear();
                numText.clear();
                roomNumText.clear();
                radioWoman.setSelected(true);
            }
        });
        checkOutText.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    checkOut();
                    checkOutText.clear();
                }
            }
        });

        nameText.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    ageText.requestFocus();
                }
            }
        });
        ageText.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    radioWoman.requestFocus();
                }
            }
        });
        radioWoman.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    idNumText.requestFocus();
                }
            }
        });
        radioMan.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    idNumText.requestFocus();
                }
            }
        });
        idNumText.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    numText.requestFocus();
                }
            }
        });
        numText.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    tableView.requestFocus();
                }
            }
        });
        tableView.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if(event.getCode() == KeyCode.ENTER)
                {
                    checkIn();
                }
            }
        });
    }

    public static void updateCheckInAndOut(Parent checkInAndOut){
        inquireRooms();//更新房间列表
    }

    private static void inquireRooms(){
        ObservableList<RoomTable> rooms = FXCollections.observableArrayList();

        //获取房间对象
        if(!singleCheckBox.isSelected() && !doubleCheckBox.isSelected() && !familyCheckBox.isSelected() && !presidentCheckBox.isSelected() && !luxuryCheckBox.isSelected() && !coupleCheckBox.isSelected()){
            //全部查询
            rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(1, database)));
            rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(2, database)));
            rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(3, database)));
            rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(4, database)));
            rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(5, database)));
            rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(6, database)));
        }
        else{
            if(singleCheckBox.isSelected()){
                rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(Room.SINGLE, database)));
            }
            if(doubleCheckBox.isSelected()){
                rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(Room.DOUBLE, database)));
            }
            if(familyCheckBox.isSelected()){
                rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(Room.FAMILY, database)));
            }
            if(presidentCheckBox.isSelected()){
                rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(Room.PRESIDENT, database)));
            }
            if(luxuryCheckBox.isSelected()){
                rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(Room.LUXURY, database)));
            }
            if(coupleCheckBox.isSelected()){
                rooms.addAll(RoomTable.getRoomTable(Room.getThroughRoomKind(Room.COUPLE, database)));
            }
        }

        //显示信息
        tableView.setItems(rooms);
    }

    private static void checkIn(){
        final String[] name = {nameText.getText()};
        if(name[0].isEmpty()){
            nameText.requestFocus();
            AlertStage.show("提示", "请输入姓名！");
            return;
        }

        if(ageText.getText().isEmpty()){
            ageText.requestFocus();
            AlertStage.show("提示", "请输入年龄！");
            return;
        }

        int age;
        try{
            age = Integer.parseInt(ageText.getText());
        }catch(NumberFormatException ex){
            ageText.requestFocus();
            AlertStage.show("错误", "年龄请输入整数！");
            return;
        }

        String sex;
        if (radioMan.isSelected()) {
            sex = "男";
        }
        else{
            sex = "女";
        }

        String idNum = idNumText.getText();
        if(idNum.isEmpty()||!idNumRight(idNum)){
            idNumText.requestFocus();
            AlertStage.show("错误", "请输入正确的身份证号码！");
            return;
        }

        if(numText.getText().isEmpty()){
            numText.requestFocus();
            AlertStage.show("错误", "请输入入住人数！");
            return;
        }

        int numberOfPeople;
        try{
            numberOfPeople = Integer.parseInt(numText.getText());
        }catch(NumberFormatException ex){
            numText.requestFocus();
            AlertStage.show("错误", "入住人数请输入整数！");
            return;
        }

        String roomNumber = roomNumText.getText();
        if(roomNumber.isEmpty()){
            tableView.requestFocus();
            AlertStage.show("错误", "请选择房间！");
            return;
        }

        Room room = Room.getThroughRoomNumber(Integer.parseInt(roomNumber), database);

        if(room == null){
            tableView.requestFocus();
            AlertStage.show("错误", "未查询到相关房间信息，请重试！");
            return;
        }

        if(room.getStatus() == 0){
            tableView.requestFocus();
            AlertStage.show("错误", "房间已经入住，请选择其他房间！");
            return;
        }

        Stage stageQrCode = new Stage();
        stageQrCode.setResizable(false);
        stageQrCode.getIcons().add(new Image("/pic/ico.png"));
        stageQrCode.setTitle("支付码");
        stageQrCode.setWidth(150);
        stageQrCode.setHeight(280);
        stageQrCode.initModality(Modality.APPLICATION_MODAL);


        Order order = new Order();
        order.order(0.01);

        ImageView imageView = new ImageView(new Image("pic/qrcode.png"));
        Button btnPay = new Button("支付成功");
        btnPay.setStyle("-fx-background-radius: 10;-fx-background-color: rgb(25,29,92);-fx-text-fill: white;-fx-font-size: 13pt;-fx-font-family: 'Microsoft YaHei UI Light';-fx-pref-height: 40;-fx-pref-width: 100;");

        Pane panePay  = new Pane(imageView,btnPay);
        panePay.setStyle("-fx-background-color: rgb(32,36,62)");
        imageView.setFitWidth(127);
        imageView.setFitHeight(127);
        imageView.setLayoutX(17.5);
        imageView.setLayoutY(5);
        btnPay.setLayoutX(35);
        btnPay.setLayoutY(165);
        panePay.setPrefWidth(150);
        panePay.setPrefHeight(280);

        btnPay.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if(order.getStatus())
                {
                    stageQrCode.close();
                    File file = new File("pic/qrcode.png");
                    file.delete();
                    //登记相关操作
                    (new History(name[0], age, sex, idNum, numberOfPeople, room.getRoomNumber())).checkIn(database);//更新历史
                    Room.setStatus(0, room.getRoomNumber(), database);//更新房间状态
                    RoomStatistics.update(room.getRoomKind(), -1, database);//房间数-1
                    //统计图表更新
                    updateGraph();
                    inquireRooms();//更新列表

                    //如果是会员则会员记录更新
                    Member member = Member.getThroughIdNumber(idNum, database);
                    if(member != null){
                        member.addPoints(database, room.getPrice());
                        AlertStage.show("成功", "登记入住成功！您当前的积分值：" + member.getPoints());
                        pane.requestFocus();
                    }
                    else {
                        AlertStage.show("成功", "登记入住成功！");
                        pane.requestFocus();
                    }

                    if(radioMan.isSelected()){
                        name[0] += "先生";
                    }
                    else{
                        name[0] += "女士";
                    }
                    server.chooseClient(room.getRoomNumber());
                    server.sendMessage("login" + "||" + name[0]);
                }
                else
                {
                    AlertStage.show("提示","支付尚未完成！");
                }
            }
        });

        Scene scenePay = new Scene(panePay);
        stageQrCode.setScene(scenePay);

        stageQrCode.show();




    }

    private static void checkOut(){
        int roomNumber;//房间号
        final boolean[] billFinished = {false};//判断订单是否完成

        try{
            roomNumber = Integer.parseInt(checkOutText.getText());
        }catch(NumberFormatException ex){
            checkOutText.requestFocus();
            AlertStage.show("错误", "请输入正确的房间号！");
            return;
        }

        Room room = Room.getThroughRoomNumber(roomNumber, database);
        if(room == null){
            AlertStage.show("错误", "请输入正确的房间号！");
            return;
        }
        if(room.getStatus() == 1){
            AlertStage.show("错误", "该房间已经办理过退房，请检查房间号是否有误！");
            return;
        }

        ResultSet resultSet = database.select("*", "bill", "roomNumber = " + roomNumber + " and status = 1");//查看消费
        try {
            if(resultSet.next()) {//存在消费行为
                double total = 0;
                ListView<String> billList = new ListView<>();
                ObservableList<String> bills = FXCollections.observableArrayList();
                billList.setEditable(false);
                billList.setItems(bills);
                billList.setPrefHeight(570);
                billList.setPrefWidth(400);


                Stage stage = new Stage();
                stage.initModality(Modality.APPLICATION_MODAL);
                stage.getIcons().add(new Image("/pic/ico.png"));
                stage.setTitle("账单确认");
                stage.setResizable(false);
                stage.setWidth(400);
                stage.setHeight(835);

                Button btnSubmit = new Button("支付成功");
                btnSubmit.setLayoutY(650);
                btnSubmit.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                        billFinished[0] = true;
                        stage.close();
                    }
                });
                Button btnCancel = new Button("取消");
                btnCancel.setLayoutY(650);
                btnCancel.setLayoutX(250);
                btnCancel.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                        stage.close();
                        AlertStage.show("提示", "支付取消！");
                    }
                });

                do{
                    bills.add(resultSet.getString(3) + "\n" + resultSet.getString(2) + "￥" + resultSet.getDouble(4));
                    total += resultSet.getDouble(4);
                }while(resultSet.next());

                Label billTotal = new Label("合计：￥" + String.valueOf(total));
                billTotal.setLayoutX(200);
                billTotal.setLayoutY(600);
                billTotal.setStyle("-fx-font-size: 20pt;-fx-text-fill: white;-fx-pref-width: 200;-fx-text-alignment: right;-fx-pref-height: 80;-fx-font-family: 'Microsoft YaHei UI Light';");

                btnSubmit.setStyle("-fx-background-radius: 10;-fx-background-color: rgb(25,29,92);-fx-text-fill: white;-fx-font-size: 13pt;-fx-font-family: 'Microsoft YaHei UI Light';-fx-pref-height: 40;-fx-pref-width: 100;");
                btnCancel.setStyle("-fx-background-radius: 10;-fx-background-color: rgb(25,29,92);-fx-text-fill: white;-fx-font-size: 13pt;-fx-font-family: 'Microsoft YaHei UI Light';-fx-pref-height: 40;-fx-pref-width: 100;");
                btnSubmit.setLayoutX(50);
                btnCancel.setLayoutX(250);
                btnCancel.setLayoutY(700);
                btnSubmit.setLayoutY(700);

                Pane pane = new Pane(billList, btnSubmit, btnCancel, billTotal);
                pane.setStyle("-fx-background-color: rgb(32,39,62)");
                stage.setScene(new Scene(pane));
                stage.showAndWait();
            }
            else{
                billFinished[0] = true;
            }
        }catch (SQLException ex){
            System.out.println("checkBillException");
        }

        if(!billFinished[0]){//订单未完成
            return;
        }

        //办理退房
        History.checkOut(database, roomNumber);//签出历史更新
        Room.setStatus(1, roomNumber, database);//房间状态更新
        RoomStatistics.update(room.getRoomKind(), 1, database);//房间统计更新
        database.update("bill", "status", "0", "roomNumber = " + roomNumber);
        //统计图表更新
        updateGraph();
        inquireRooms();//更新列表
        server.chooseClient(roomNumber);
        server.sendMessage("logout");
        AlertStage.show("成功", "退房成功！");
    }

    private static void updateGraph() {//统计图更新
        RoomStatistics roomStatistics = new RoomStatistics(database);
        Stage1.cleanGraph();
        roomStatistics.inquire(Room.SINGLE);
        Stage1.SingleChange(roomStatistics.getRoomsTotal(), roomStatistics.getRoomsLeft());
        roomStatistics.inquire(Room.DOUBLE);
        Stage1.DoubleChange(roomStatistics.getRoomsTotal(), roomStatistics.getRoomsLeft());
        roomStatistics.inquire(Room.PRESIDENT);
        Stage1.PresidentChange(roomStatistics.getRoomsTotal(), roomStatistics.getRoomsLeft());
        roomStatistics.inquire(Room.LUXURY);
        Stage1.LuxuryChange(roomStatistics.getRoomsTotal(), roomStatistics.getRoomsLeft());
        roomStatistics.inquire(Room.COUPLE);
        Stage1.CoupleChange(roomStatistics.getRoomsTotal(), roomStatistics.getRoomsLeft());
        roomStatistics.inquire(Room.FAMILY);
        Stage1.FamilyChange(roomStatistics.getRoomsTotal(), roomStatistics.getRoomsLeft());
        }


    public static boolean idNumRight(String s) {
        if (s.length() != 18) {
            return false;
        }
        int sum;
        try{
            sum = Integer.parseInt(s.substring(0, 1)) * 7 +
                    Integer.parseInt(s.substring(1, 2)) * 9 +
                    Integer.parseInt(s.substring(2, 3)) * 10 +
                    Integer.parseInt(s.substring(3, 4)) * 5 +
                    Integer.parseInt(s.substring(4, 5)) * 8 +
                    Integer.parseInt(s.substring(5, 6)) * 4 +
                    Integer.parseInt(s.substring(6, 7)) * 2 +
                    Integer.parseInt(s.substring(7, 8)) * 1 +
                    Integer.parseInt(s.substring(8, 9)) * 6 +
                    Integer.parseInt(s.substring(9, 10)) * 3 +
                    Integer.parseInt(s.substring(10, 11)) * 7 +
                    Integer.parseInt(s.substring(11, 12)) * 9 +
                    Integer.parseInt(s.substring(12, 13)) * 10 +
                    Integer.parseInt(s.substring(13, 14)) * 5 +
                    Integer.parseInt(s.substring(14, 15)) * 8 +
                    Integer.parseInt(s.substring(15, 16)) * 4 +
                    Integer.parseInt(s.substring(16, 17)) * 2;}
        catch (NumberFormatException ex)
        {
            return false;
        }
        sum = sum % 11;
        char finalNum = s.charAt(17);
        switch (sum) {
            case 0:
                if (finalNum == '1') return true;
                else return false;
            case 1:
                if (finalNum == '0') return true;
                else return false;
            case 2:
                if (finalNum == 'X') return true;
                else return false;
            case 3:
                if (finalNum == '9') return true;
                else return false;
            case 4:
                if (finalNum == '8') return true;
                else return false;
            case 5:
                if (finalNum == '7') return true;
                else return false;
            case 6:
                if (finalNum == '6') return true;
                else return false;
            case 7:
                if (finalNum == '5') return true;
                else return false;
            case 8:
                if (finalNum == '4') return true;
                else return false;
            case 9:
                if (finalNum == '3') return true;
                else return false;
            case 10:
                if (finalNum == '2') return true;
                else return false;
        }
        return true;
    }

}
